<template>
  <div class="page">
    <!-- 顶部栏 -->
    <van-nav-bar>
      <template #left>
        <div class="title">{{ $t('兑换') }}</div>
      </template>

      <template #right>
        <div class="flex flex-cc">
          <!-- 隐藏的钱包地址 -->
          <div class="address fz-12 cl-white bcl-success mr-10">
            {{ fromAddressHideRef }}
          </div>

          <!-- 选择语言 -->
          <select-lang></select-lang>
        </div>
      </template>
    </van-nav-bar>

    <!-- 内容 -->
    <div class="box">
      <!-- 选择兑换类型 -->
      <div class="flex flex-rr mb-15">
        <select-exchange @select-exchange="onSelectChange"></select-exchange>
      </div>

      <div class="container box radius cl-white">
        <!-- 发送方 -->
        <div>
          <div class="flex flex-cc flex-rb mb-10">
            <div>{{ $t('发送') }}</div>
            <div>
              <span>{{ $t('余额') }}：</span>
              <span>{{ balance }}</span>
            </div>
          </div>

          <div class="box box--border flex flex-cc flex-rb">
            <div class="flex flex-cc flex-fs-0">
              <div class="fz-15 fw-bold">{{ sender.name }}</div>
            </div>
            <div class="flex flex-cc">
              <van-field
                :placeholder="$t('兑换金额')"
                v-model="amount"
              ></van-field>
              <van-button
                style="width: 70px; height: 32px"
                color="#f1b135"
                round
                @click="amount = balance"
              >
                MAX
              </van-button>
            </div>
          </div>
        </div>

        <div class="flex flex-rc mt-10">
          <img style="width: 30px" src="../assets/img/exchange.png" />
        </div>

        <!-- 接收方 -->
        <div class="mb-30">
          <div class="mb-10">{{ $t('接收') }}</div>

          <div class="box box--border flex flex-cc flex-rb">
            <div class="flex flex-cc flex-fs-0">
              <div class="fz-15 fw-bold">{{ receiver.name }}</div>
            </div>
            <van-field v-model="amount"></van-field>
          </div>
        </div>

        <!-- 兑换按钮 -->
        <div class="flex flex-rc mb-30">
          <van-button
            style="width: 250px"
            color="#f1b135"
            round
            @click="exchange"
          >
            {{ $t('兑换') }}
          </van-button>
        </div>

        <!-- 配置 -->
        <div class="box box--border mb-30">
          <div
            class="flex flex-rb pb-10 mb-10"
            style="border-bottom: 1px dashed var(--color-border)"
          >
            <div>{{ $t('最小兑换数量') }}</div>
            <div>1</div>
          </div>
          <div class="flex flex-rb">
            <div>{{ $t('手续费') }}</div>
            <div>0%</div>
          </div>
        </div>

        <!-- 兑换明细 -->
        <div>
          <div class="cl-black mb-10">{{ $t('兑换明细') }}</div>

          <div v-if="orders.length">
            <ul>
              <li
                class="box box--border mb-10"
                v-for="(v, i) in orders"
                :key="i"
              >
                <div>
                  <span>{{ $t('兑换金额') }}：</span>
                  <span>{{ v.amount }}</span>
                </div>
                <div>
                  <span>{{ $t('兑换代币') }}：</span>
                  <span>{{ v.wrapperType }}</span>
                </div>
                <div>
                  <span>{{ $t('时间') }}：</span>
                  <span>{{ v.createTime }}</span>
                </div>
              </li>
            </ul>

            <van-pagination
              :prev-text="$t('上一页')"
              :next-text="$t('下一页')"
              :page-count="pageCount"
              @change="getOrderList"
              v-model="page"
            ></van-pagination>
          </div>

          <van-empty :description="$t('暂无数据')" v-else></van-empty>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { toBigNumber, toNumber, showToast, showLoading } from 'js/utils'
import cosmo from 'cosmo-wallet-tool'
import api from 'js/api'

import selectExchange from 'comps/selectExchange.vue'
import selectLang from 'comps/selectLang.vue'

// 隐藏的钱包地址
const fromAddressHideRef = ref(window.fromAddressHide)

// 当前兑换类型
const currentExchange = ref({})

// 发送方
const sender = ref({})

// 接收方
const receiver = ref({})

// 余额
const balance = ref('')

// 兑换金额
const amount = ref('')

// 兑换明细
const orders = ref([])
const page = ref(1)
const pageSize = ref(5)
const pageCount = ref(1)

const isWallet = ref(false)

onMounted(async () => {
  isWallet.value = await cosmo.isWallet
})

// 获取钱包余额
async function getBalance() {
  const toolName = isWallet.value ? 'walletTool' : 'chromeTool'
  const { value } = currentExchange.value

  if (value === 2) {
    // PC
    const { balance: data } = await api.getPcBalance(fromAddress)
    balance.value = toNumber(data.amount)
  } else {
    // 其他
    const result = await cosmo[toolName].contractCall(
      cosmo.addressForBech32ToHex(sender.value.address),
      'balanceOf(address)',
      [cosmo.addressForBech32ToHex(fromAddress)]
    )

    balance.value = toNumber(isWallet.value ? result.data : result)
  }
}

// 兑换
async function exchange() {
  try {
    if (!amount.value) {
      return showToast($t('请输入兑现金额'))
    }

    if (amount.value < 1) {
      return showToast($t('最小兑换数量为1'))
    }

    if (amount.value > balance.value) {
      return showToast($t('超过最大兑换数量'))
    }

    const toolName = isWallet.value ? 'walletTool' : 'chromeTool'
    const { value } = currentExchange.value

    showLoading()

    if (value === 0) {
      // PUSD -> PUSD-HASH

      // 授权对象
      let approve = null

      // 获取已授权的余额
      const result = await cosmo[toolName].contractCall(
        cosmo.addressForBech32ToHex(sender.value.address),
        'allowance(address,address)',
        [
          cosmo.addressForBech32ToHex(fromAddress),
          cosmo.addressForBech32ToHex(receiver.value.address),
        ]
      )

      const balance = toNumber(isWallet.value ? result.data : result)
      console.log('balance：', balance)

      if (balance >= amount.value) {
        // 无需授权
        approve = { data: '无需授权', noToast: true }
      } else {
        // 授权
        approve = await cosmo[toolName].contractSend(
          cosmo.addressForBech32ToHex(sender.value.address),
          'approve(address,uint256)',
          [cosmo.addressForBech32ToHex(receiver.value.address), '1000000']
        )
      }

      console.log('approve：', approve)

      if (checkIsSuccess(approve) || approve?.data === '无需授权') {
        if (!approve.noToast) {
          showToast($t('授权成功'))
        }

        // 转账
        const transfer = await cosmo[toolName].contractSend(
          cosmo.addressForBech32ToHex(receiver.value.address),
          'wrapper(uint256)',
          [toBigNumber(amount.value)]
        )

        console.log('transfer：', transfer)

        if (checkIsSuccess(transfer)) {
          amount.value = ''
          showToast($t('兑换成功'))
          addOrder({ type: 2, payStatus: 1 })
        } else {
          showToast($t('兑换失败'))
          addOrder({ type: 2, payStatus: 2 })
        }
      } else {
        showToast($t('授权失败'))
      }
    } else if (value === 1) {
      // PUSD-HASH -> PUSD

      // 转账
      const transfer = await cosmo[toolName].contractSend(
        cosmo.addressForBech32ToHex(sender.value.address),
        'transfer(address,uint256)',
        [
          cosmo.addressForBech32ToHex(sender.value.address),
          toBigNumber(amount.value),
        ]
      )

      console.log('transfer：', transfer)

      if (checkIsSuccess(transfer)) {
        amount.value = ''
        showToast($t('兑换成功'))
        addOrder({ type: 2, payStatus: 1 })
      } else {
        showToast($t('兑换失败'))
        addOrder({ type: 2, payStatus: 2 })
      }
    } else if (value === 2) {
      // PC -> PC-HASH

      // 转账
      let transfer = null

      if (isWallet.value) {
        transfer = await cosmo[toolName].contractSend(
          cosmo.addressForBech32ToHex(receiver.value.address),
          'wrapper()',
          [],
          undefined,
          toBigNumber(amount.value)
        )
      } else {
        transfer = await cosmo[toolName].contractSendRaw(
          cosmo.addressForBech32ToHex(receiver.value.address),
          '0x',
          toBigNumber(amount.value)
        )
      }

      console.log('transfer：', transfer)

      if (checkIsSuccess(transfer)) {
        amount.value = ''
        showToast($t('兑换成功'))
        addOrder({ type: 1, payStatus: 1 })
      } else {
        showToast($t('兑换失败'))
        addOrder({ type: 1, payStatus: 2 })
      }
    } else if (value === 3) {
      // PC-HASH -> PC

      // 转账
      const transfer = await cosmo[toolName].contractSend(
        cosmo.addressForBech32ToHex(sender.value.address),
        'transfer(address,uint256)',
        [
          cosmo.addressForBech32ToHex(sender.value.address),
          toBigNumber(amount.value),
        ]
      )

      console.log('transfer：', transfer)

      if (checkIsSuccess(transfer)) {
        amount.value = ''
        showToast($t('兑换成功'))
        addOrder({ type: 1, payStatus: 1 })
      } else {
        showToast($t('兑换失败'))
        addOrder({ type: 1, payStatus: 2 })
      }
    }
  } catch (err) {
    showToast($t('兑换失败'))
  }
}

// 增加兑换明细
async function addOrder(extraParams = {}) {
  const params = {
    isEth: 1,
    groupCode: 'REDEEM_ORDER',
    walletAddress: fromAddress,
    loading: false,
    ...extraParams,
  }

  const { code } = await api.addOrder(params)

  if (code === 200) {
    page.value = 1
    getOrderList(false)
  }
}

// 获取兑换明细
async function getOrderList(loading = true) {
  const { value } = currentExchange.value

  const params = {
    type: [0, 1].includes(value) ? 2 : 1,
    walletAddress: fromAddress,
    current: page.value,
    size: pageSize.value,
    loading,
  }

  const { code, data } = await api.getOrderList(params)

  if (code === 200) {
    const { records = [], total = 0 } = data
    orders.value = records
    pageCount.value = Math.ceil(total / pageSize.value)
  }
}

// 检查是否成功
function checkIsSuccess(target) {
  if (isWallet.value) {
    return target && target?.status === 0
  } else {
    return target && typeof target === 'string'
  }
}

// 选择兑换类型
function onSelectChange(e) {
  currentExchange.value = e
  sender.value = e.sender
  receiver.value = e.receiver
  amount.value = ''

  setTimeout(() => {
    getBalance()
    getOrderList()
  }, 0)
}
</script>

<style lang="scss" scoped>
:deep(.van-nav-bar) {
  .van-haptics-feedback {
    &:active {
      opacity: 1 !important;
    }
  }

  .address {
    padding: 0 5px;
    border-radius: 100px;
  }
}

.container {
  min-height: 100vh;
  background: linear-gradient(to bottom, var(--color-success), white 600px);
}

.box--border {
  box-shadow: 0 0 4px 3px var(--color-success) inset;
  background-color: white;
  color: var(--color-black);
  border-radius: 4px;
}

:deep(.van-button) {
  height: 40px;

  .van-button__content {
    font-size: 15px;
    font-weight: bolder;
  }
}

:deep(.van-field) {
  width: 100px;

  input {
    text-align: right;
  }
}
</style>
